package com.zxm.sunshineaiary.view.calendar.datewidgetdaycell;

import java.util.ArrayList;
import java.util.Calendar;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.zxm.sunshineaiary.activity.R;
import com.zxm.sunshineaiary.sql.service.SqlService;
import com.zxm.sunshineaiary.util.CharsUtil;
import com.zxm.sunshineaiary.view.calendar.datewidgetdaycell.DateWidgetDayCell.OnItemClick;

public class DateWidgetDay extends FrameLayout {

	private final String TAG = "DateWidgetDay";

	private Context mContext = null;
	private DateWidgetDayInfo mDateWidgetDayInfo = DateWidgetDayInfo
			.getinstance();

	private Calendar calStartDate = Calendar.getInstance();
	private Calendar calToday = Calendar.getInstance();
	private Calendar calCalendar = Calendar.getInstance();
	private Calendar calSelected = Calendar.getInstance();
	private SqlService msqService = null;

	private int iMonthViewCurrentMonth = 10;
	private ArrayList<DateWidgetDayCell> days = new ArrayList<DateWidgetDayCell>();

	public int iDay = 0;// 离周日的距离

	/**
	 * 一天日期的大小
	 */
	private int iDayCellSizeW = 55;
	private int iDayCellSizeH = 70;
	private int iFirstDayOfWeek;
	private int mYear;
	private int mMonth;
	private int mDay;

	public DateWidgetDay(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
		this.setDateWidgetDayInfo(context, attrs);
		this.setDayOfWeek();
		this.addView(generateContentView());
		calStartDate = getCalendarStartDate();
		msqService = SqlService.getInstance(context);
		updateCalendar();
		setDiarybackgroud();
	}

	public DateWidgetDay(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.mContext = context;
		this.setDateWidgetDayInfo(context, attrs);
		this.setDayOfWeek();
		this.addView(generateContentView());
		calStartDate = getCalendarStartDate();
		msqService = SqlService.getInstance(context);
		updateCalendar();
		setDiarybackgroud();
	}

	public DateWidgetDay(Context context) {
		super(context);
		this.mContext = context;
		this.setDayOfWeek();
		this.addView(generateContentView());
		calStartDate = getCalendarStartDate();
		msqService = SqlService.getInstance(context);
		updateCalendar();
		setDiarybackgroud();
	}

	/**
	 * 从XML读取控件属性
	 * 
	 * @param context
	 * @param attrs
	 */
	private void setDateWidgetDayInfo(Context context, AttributeSet attrs) {
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.DateWidgetDay);
		float textSize = a.getDimension(R.styleable.DateWidgetDay_textSize, 10);
		mDateWidgetDayInfo.setfTextSize(textSize);
		iDayCellSizeW = (int) a.getDimension(
				R.styleable.DateWidgetDay_childItemWith, 10);
		iDayCellSizeH = (int) a.getDimension(
				R.styleable.DateWidgetDay_childItemHight, 10);
	}

	/**
	 * 获得当前月份
	 * 
	 * @return
	 */
	public int getTodayMonth() {
		return mMonth;
	}

	/**
	 * 获得日期布局
	 * 
	 * @return
	 */
	private View generateContentView() {
		LinearLayout layMain = createLayout(LinearLayout.VERTICAL);
		LinearLayout layContent = createLayout(LinearLayout.VERTICAL);
		layContent.setPadding(0, 0, 0, 0);
		generateCalendar(layContent);
		layMain.addView(layContent);

		return layMain;
	}

	private DateWidgetDayCell updateCalendar() {
		DateWidgetDayCell daySelected = null;
		boolean bSelected = false;
		boolean bHoliday = false;
		final boolean bIsSelection = (calSelected.getTimeInMillis() != 0);
		final int iSelectedYear = calSelected.get(Calendar.YEAR);
		final int iSelectedMonth = calSelected.get(Calendar.MONTH);
		final int iSelectedDay = calSelected.get(Calendar.DAY_OF_MONTH);
		calCalendar.setTimeInMillis(calStartDate.getTimeInMillis());
		for (int i = 0; i < days.size(); i++) {
			final int iYear = calCalendar.get(Calendar.YEAR);
			final int iMonth = calCalendar.get(Calendar.MONTH);
			final int iDay = calCalendar.get(Calendar.DAY_OF_MONTH);
			final int iDayOfWeek = calCalendar.get(Calendar.DAY_OF_WEEK);
			DateWidgetDayCell dayCell = days.get(i);
			// check today
			boolean bToday = false;
			if (calToday.get(Calendar.YEAR) == iYear)
				if (calToday.get(Calendar.MONTH) == iMonth)
					if (calToday.get(Calendar.DAY_OF_MONTH) == iDay) {
						bToday = true;
					}

			if ((iDayOfWeek == Calendar.SATURDAY)
					|| (iDayOfWeek == Calendar.SUNDAY)) {
				bHoliday = true;
			}

			if ((iMonth == Calendar.JANUARY) && (iDay == 1)) {
				bHoliday = true;
			}

			dayCell.setData(iYear, iMonth, iDay, bToday, bHoliday,
					iMonthViewCurrentMonth);
			bSelected = false;
			if (bIsSelection)
				if ((iSelectedDay == iDay) && (iSelectedMonth == iMonth)
						&& (iSelectedYear == iYear)) {
					bSelected = true;
				}
			dayCell.setSelected(bSelected);
			if (bSelected)
				daySelected = dayCell;
			calCalendar.add(Calendar.DAY_OF_MONTH, 1);
		}

		return daySelected;
	}

	/**
	 * 根据从数据库查询的日记日期，设置日历背景颜色
	 */
	public void setDiarybackgroud() {
		final int iSelectedYear = calCalendar.get(Calendar.YEAR);
		final int iSelectedMonth = calCalendar.get(Calendar.MONTH);

		String month = CharsUtil.accountDateString(iSelectedMonth);

		ArrayList<Integer> list = msqService.getDiaryDateDay(
				iSelectedYear + "", month + "");
		if (null != list) {

			for (DateWidgetDayCell widgtDayCell : days) {
				widgtDayCell.setDateBackgroudFalse();
			}
			for (int i = 0; i < list.size(); i++) {
				int posation = (list.get(i) - 1) + iDay;
				DateWidgetDayCell widgtDayCell = days.get(posation);
				widgtDayCell.setDateBackgroudTrue();
			}
		} else {
			for (DateWidgetDayCell widgtDayCell : days) {
				widgtDayCell.setDateBackgroudFalse();
			}
		}
	}

	private Calendar getCalendarStartDate() {
		calToday.setTimeInMillis(System.currentTimeMillis());
		calToday.setFirstDayOfWeek(iFirstDayOfWeek);

		if (calSelected.getTimeInMillis() == 0) {
			calStartDate.setTimeInMillis(System.currentTimeMillis());
			calStartDate.setFirstDayOfWeek(iFirstDayOfWeek);
		} else {
			calStartDate.setTimeInMillis(calSelected.getTimeInMillis());
			calStartDate.setFirstDayOfWeek(iFirstDayOfWeek);
		}
		UpdateStartDateForMonth();

		return calStartDate;
	}

	/**
	 * 设置日历日期
	 * 
	 * @param year
	 * @param month
	 */
	public void setDateWidgetDay(int year, int month) {

		calStartDate.set(Calendar.DAY_OF_MONTH, 1);
		calStartDate.set(Calendar.MONTH, month);
		calStartDate.set(Calendar.YEAR, year);
		UpdateStartDateForMonth();
		updateCalendar();
		setDiarybackgroud();

		Log.v(TAG, calStartDate.get(Calendar.DAY_OF_MONTH) + "");
		this.invalidate();
	}

	/**
	 * 根据月份来排序日期
	 */
	private void UpdateStartDateForMonth() {
		iMonthViewCurrentMonth = calStartDate.get(Calendar.MONTH);
		calStartDate.set(Calendar.DAY_OF_MONTH, 1);
		updateCurrentMonthDisplay();
		// update days for week
		iDay = 0;
		int iStartDay = iFirstDayOfWeek;
		if (iStartDay == Calendar.MONDAY) {
			iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.MONDAY;
			if (iDay < 0)
				iDay = 6;
		}
		if (iStartDay == Calendar.SUNDAY) {
			iDay = calStartDate.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
			if (iDay < 0)
				iDay = 6;
		}
		Log.v(TAG, "iDay===" + iDay);
		calStartDate.add(Calendar.DAY_OF_WEEK, -iDay);
	}

	private void updateCurrentMonthDisplay() {
		String s = calCalendar.get(Calendar.YEAR) + "/"
				+ (calCalendar.get(Calendar.MONTH) + 1);// dateMonth.format(calCalendar.getTime());
		mYear = calCalendar.get(Calendar.YEAR);
	}

	/**
	 * 创建日期布局
	 * 
	 * @param iOrientation
	 * @return
	 */
	private LinearLayout createLayout(int iOrientation) {
		LinearLayout linearLayou = new LinearLayout(mContext);
		linearLayou.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT));
		linearLayou.setOrientation(iOrientation);
		return linearLayou;
	}

	/**
	 * 把日期地址加入布局
	 * 
	 * @param layContent
	 */
	private void generateCalendar(LinearLayout layContent) {
		days.clear();
		for (int iRow = 0; iRow < 6; iRow++) {
			layContent.addView(generateCalendarRow());
		}
	}

	/**
	 * 创建单个日期
	 * 
	 * @return
	 */
	private View generateCalendarRow() {
		LinearLayout layRow = createLayout(LinearLayout.HORIZONTAL);
		for (int iDay = 0; iDay < 7; iDay++) {
			DateWidgetDayCell dayCell = new DateWidgetDayCell(mContext,
					iDayCellSizeW, iDayCellSizeH);
			days.add(dayCell);
			layRow.addView(dayCell);
		}
		return layRow;
	}

	/**
	 * 得到当前日期
	 */
	private void setDayOfWeek() {
		this.iFirstDayOfWeek = Calendar.MONDAY;
		this.mYear = calStartDate.get(Calendar.YEAR);
		this.mMonth = calStartDate.get(Calendar.MONTH);
		this.mDay = calStartDate.get(Calendar.DAY_OF_MONTH);

		Log.v(TAG, "iFirstDayOfWeek====" + iFirstDayOfWeek);
		Log.v(TAG, "mYear====" + mYear);
		Log.v(TAG, "mMonth====" + mMonth);
		Log.v(TAG, "mDay====" + mDay);
		Log.v(TAG, calStartDate.get(Calendar.DAY_OF_YEAR) + "");

	}

	/**
	 * 注册监听事件
	 * 
	 * @param itemClick
	 */
	public void setOnItemClickListener(OnItemClick itemClick) {
		int dayNum = getMonthDays(calStartDate.get(Calendar.YEAR), calStartDate
				.get(Calendar.MONTH))
				- iDay;
		for (int i = iDay; i < dayNum; i++) {
			days.get(i).setOnItemClickListener(itemClick);
		}
	}

	/**
	 * 获得每月有多少天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public int getMonthDays(int year, int month) {
		int lastMonthDays = 0;
		switch (month) {
		case 2:
			if (isRn(year))
				lastMonthDays = 28;
			else
				lastMonthDays = 29;
			break;
		case 4:
			lastMonthDays = 30;
			break;
		case 6:
			lastMonthDays = 30;
			break;
		case 9:
			lastMonthDays = 30;
			break;
		case 11:
			lastMonthDays = 30;
			break;
		default:
			lastMonthDays = 31;
		}
		return lastMonthDays;
	}

	/**
	 * 闰年
	 * 
	 * @param year
	 * @return
	 */
	public boolean isRn(int year) {
		if (year % 4 == 0 && !(year % 100 == 0 && year % 400 != 0))
			return true;
		return false;
	}

	public int getiDay() {
		return iDay;
	}
}
